<template>
  <div class="app-container">
    <el-row :gutter="20" class="div-height-left">
      <el-col v-if="userInfo.userId === '1'" :span="4" class="div-height-left">
        <sys-org-tree @treeClick="treeClick"/>
      </el-col>
      <el-col :span="userInfo.userId === '1' ? 20 : 24" :xs="24">
        <div class="search-container">
          <el-form v-show="showSearch" ref="queryParamsRef" :inline="true" :model="queryParams"
                   label-width="80px">
            <el-form-item label="角色名称" prop="roleName">
              <el-input v-model="queryParams.roleName" clearable placeholder="请输入角色名称"
                        @keyup.enter.native="handleQuery"/>
            </el-form-item>
            <el-form-item label="权限字符" prop="roleKey">
              <el-input v-model="queryParams.roleKey" clearable placeholder="请输入权限字符"
                        @keyup.enter.native="handleQuery"/>
            </el-form-item>
            <el-form-item label="角色状态" prop="status">
              <el-radio-group v-model="queryParams.status" @change="handleQuery">
                <el-radio value="">全部</el-radio>
                <el-radio v-for="dict in dictDataMap['sys_normal_disable']" :key="dict.dictValue"
                          :value="dict.dictValue">{{
                    dict.dictLabel
                  }}
                </el-radio>
              </el-radio-group>
            </el-form-item>
            <div style="float: right">
              <query-form-button @handleQuery="handleQuery" @resetQuery="resetQuery"/>
            </div>
          </el-form>
        </div>
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button v-hasPerm="['system:role:add']" plain type="primary" @click="handleAdd">
              <template
                #icon>
                <i-ep-plus/>
              </template>
              新增
            </el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button v-hasPerm="['system:role:remove']" :disabled="multiple" plain type="danger"
                       @click="handleDelete">
              <template #icon>
                <i-ep-delete/>
              </template>
              删除
            </el-button>
          </el-col>
          <!--            <el-col :span="1.5">-->
          <!--                <el-button-->
          <!--                    type="warning"-->
          <!--                    plain-->
          <!--                    icon="el-icon-download"-->
          <!--                    -->
          <!--                    @click="handleExport"-->
          <!--                    v-hasPerm="['system:role:export']"-->
          <!--                >导出-->
          <!--                </el-button>-->
          <!--            </el-col>-->
        </el-row>

        <el-table v-adaptive :border="true" :data="roleList" :header-cell-style="$headerCellStyle" :stripe="true"
                  highlight-current-row @selection-change="handleSelectionChange">
          <el-table-column :align="'center'" type="selection" width="55"/>
          <!--            <el-table-column label="角色编号" prop="roleId" :header-align="'center'" width="120"/>-->
          <el-table-column :header-align="'center'" :show-overflow-tooltip="true" label="角色名称"
                           prop="roleName"/>
          <el-table-column :header-align="'center'" :show-overflow-tooltip="true" label="权限字符"
                           prop="roleKey"/>
          <el-table-column :align="'center'" label="显示顺序" prop="roleSort" width="100"/>
          <el-table-column :align="'center'" label="状态" width="100">
            <template #default="scope">
              <el-switch v-model="scope.row.status" active-value="0" inactive-value="1"
                         @change="handleStatusChange(scope.row)"></el-switch>
            </template>
          </el-table-column>
          <el-table-column :align="'center'" label="创建时间" prop="createTime" width="180">
            <template #default="scope">
              <span>{{ $parseTime(scope.row.createTime) }}</span>
            </template>
          </el-table-column>
          <el-table-column :align="'center'" class-name="small-padding fixed-width" label="操作" width="300">
            <template #default="scope">
              <div v-if="scope.row.roleId !== 1">
                <el-button v-hasPerm="['system:role:edit']" type="primary"
                           @click="handleUpdate(scope.row)">
                  <template #icon>
                    <i-ep-edit/>
                  </template>
                  权限分配
                </el-button>
                <el-button v-hasPerm="['system:role:edit']" type="warning"
                           @click="handleAuthUser(scope.row)">
                  <template #icon>
                    <i-ep-user/>
                  </template>
                  分配人员
                </el-button>
                <el-button v-hasPerm="['system:role:remove']" icon="el-icon-delete" type="danger"
                           @click="handleDelete(scope.row)">
                  <template #icon>
                    <i-ep-delete/>
                  </template>
                  删除
                </el-button>
                <!--                    <el-dropdown  @command="(command) => handleCommand(command, scope.row)"-->
                <!--                                 v-hasPerm="['system:role:edit']">-->
                <!--                        <span class="el-dropdown-link">-->
                <!--                          <i class="el-icon-d-arrow-right el-icon&#45;&#45;right"></i>更多-->
                <!--                        </span>-->
                <!--                        <el-dropdown-menu slot="dropdown">-->
                <!--                            <el-dropdown-item command="handleAuthUser" icon="el-icon-user"-->
                <!--                                              v-hasPerm="['system:role:edit']">分配用户-->
                <!--                            </el-dropdown-item>-->
                <!--                        </el-dropdown-menu>-->
                <!--                    </el-dropdown>-->
              </div>

            </template>
          </el-table-column>
        </el-table>

        <pagination v-show="total > 0" v-model:limit="queryParams.pageSize" v-model:page="queryParams.pageNum"
                    :total="total" @pagination="getList"/>
      </el-col>
    </el-row>
    <!-- 添加或修改角色配置对话框 -->
    <el-dialog v-model="open" :close-on-click-modal="false" :title="title" append-to-body width="1200px"
               @close="chooseClose">
      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
        <el-row :gutter="40">
          <el-col :span="9">
            <el-form-item label="角色名称" prop="roleName">
              <el-input v-model="form.roleName" placeholder="请输入角色名称"/>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item prop="roleKey">
              <template #label>
                <div>
                  权限字符
                  <el-tooltip effect="light" placement="bottom">
                    <template #content>控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasRole('admin')`)
                    </template>
                    <i-ep-QuestionFilled class="inline-block" style="margin-bottom: -3px;"/>
                  </el-tooltip>
                </div>
              </template>

              <el-input v-model="form.roleKey" placeholder="请输入权限字符"/>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="角色顺序" prop="roleSort">
              <el-input-number v-model="form.roleSort" :min="0" controls-position="right"/>
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="状态">
          <el-radio-group v-model="form.status">
            <el-radio v-for="dict in dictDataMap['sys_normal_disable']" :key="dict.dictValue"
                      :value="dict.dictValue">{{
                dict.dictLabel
              }}
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="服务选择">
          <div class="parent-div">
            <div class="parent-div mr10 df1 child-heigth-auto">
              <div class="df1 child-heigth-auto">
                <el-card class="box-card" style="height: 100%;">
                  <template #header>
                    <div class="card-header">
                      <span>待选服务</span>
                      <span style="float: right;">{{ leftChoose.length }}/{{
                          chooseService.length
                        }}</span>
                    </div>
                  </template>
                  <div>
                    <el-empty v-if="chooseService.length === 0" description="无数据"
                              style="margin-bottom: -310px;"/>
                    <el-checkbox-group v-model="leftChoose" @change="leftChooseChange">
                      <div v-for="(item, index) in chooseService">
                        <el-checkbox :key="item.roleGroupId" :label="item"
                                     class="check-service">{{
                            item.roleGroupName
                          }}
                        </el-checkbox>
                      </div>
                    </el-checkbox-group>
                  </div>
                </el-card>
              </div>
              <div class="mr10" style="align-self: center;margin-left: 8px;">
                <div>
                  <el-button :disabled="leftChoose.length === 0" type="primary"
                             @click="theSelected">选中
                  </el-button>
                  <el-button :disabled="rightChoose.length === 0" type="danger" @click="theCancel">删除
                  </el-button>
                </div>
              </div>
              <div class="df1 child-heigth-auto">
                <el-card class="box-card" style="height: 100%;">
                  <template #header>
                    <div class="card-header">
                      <span>已选服务</span>
                      <span style="float: right;">{{ rightChoose.length }}/{{
                          haveChooseService.length
                        }}</span>
                    </div>
                  </template>
                  <div>
                    <el-empty v-if="haveChooseService.length === 0" description="无数据"
                              style="margin-bottom: -310px;"/>
                    <el-checkbox-group v-model="rightChoose" @change="rightChooseChange">
                      <div v-for="(item, index) in haveChooseService">
                        <el-checkbox :key="item.roleGroupId" :label="item"
                                     class="check-service">{{
                            item.roleGroupName
                          }}
                        </el-checkbox>
                      </div>
                    </el-checkbox-group>
                  </div>
                </el-card>
              </div>
            </div>

            <!-- 服务对应的菜单明细 -->
            <div class="mr10 df06 div-border child-heigth-auto">
              <div class="tree-div">
                <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">
                  展开/折叠
                </el-checkbox>
                <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">
                  全选/全不选
                </el-checkbox>
                <el-checkbox v-model="menuCheckStrictly"
                             @change="handleCheckedTreeConnect($event, 'menu')">
                  父子联动
                </el-checkbox>
              </div>
              <div class="group-menu-tree">
                <el-empty v-if="menuOptions.length === 0" description="无数据"
                          style="margin-bottom: -310px;"/>
                <div v-else>
                  <el-tree ref="menu" :check-strictly="!form.menuCheckStrictly" :data="menuOptions"
                           :props="defaultProps" class="tree-border" default-expand-all
                           empty-text="加载中，请稍候" node-key="id" show-checkbox
                           style="height: 100%;"></el-tree>
                </div>
              </div>
            </div>
          </div>

        </el-form-item>
        <el-form-item label=" 备注">
          <el-input v-model="form.remark" placeholder="请输入内容" type="textarea"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
                <span class="dialog-footer">
                    <el-button type="primary" @click="submitForm">确 定</el-button>
                    <el-button @click="chooseClose">取 消</el-button>
                </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import {addRole, changeRoleStatus, delRole, listRole, updateRole} from "@/api/system/role";
import {selectChooseRoleGroupMenu} from "@/api/system/menu";
import {getNotExistsRoleGroup, selectList} from "@/api/system/group";
import {roleGroupMenuTree} from '@/api/system/roleGroupMenu'
import {delChooseRoleGroup} from '@/api/system/chooseRoleGroup'
import {useUserStoreHook} from "@/store/modules/user";
import {useDictStoreHook} from "@/store/modules/dict";
import {useRouter} from "vue-router";

const useUserStore = useUserStoreHook();
const {proxy} = getCurrentInstance() as any
const dictStore = useDictStoreHook()
const dictDataMap = ref(dictStore.isTypeGetData('sys_normal_disable'))
const router = useRouter()
// 登录用户信息
const userInfo = <UserInfoBusi>useUserStore.user.userInfo
const formRef = ref()
const dept = ref()
const menu = ref()
const deptOptions = ref()
// 权限菜单数量
const menuCount = ref(0)
// 是否点击新增按钮
const isAdd = ref(false)
// 已选择服务id
const roleGroupId = ref('')
// 菜单树选择项是否关联显示
const menuCheckStrictly = ref(true)
// 待选择服务列表
const chooseService = ref<any>([])
// 已选择服务列表
const haveChooseService = ref<any>([])
// 左侧选中
const leftChoose = ref([])
// 右侧选中
const rightChoose = ref<any>([])
// 页面临时删除的服务列表
const deleteList = ref([])
const value = ref([])
// 选中数组
const ids = ref([])
// 非单个禁用
const single = ref(true)
// 非多个禁用
const multiple = ref(true)
// 显示搜索条件
const showSearch = ref(true)
// 总条数
const total = ref(0)
// 角色表格数据
const roleList = ref([])
// 弹出层标题
const title = ref("")
// 是否显示弹出层
const open = ref(false)
// 是否显示弹出层（数据权限）
const openDataScope = ref(false)
const menuExpand = ref(true)
const menuNodeAll = ref(false)
// 日期范围
const dateRange = ref([])
// 菜单列表
const menuOptions = ref([])
// 查询参数
const queryParamsRef = ref()
const queryParams = ref<any>({
  pageNum: 1,
  pageSize: 10,
  roleName: undefined,
  roleKey: undefined,
  status: ''
})
const defaultProps = ref({
  children: "children",
  label: "label"
})
// 表单参数
const form = ref<any>({})

// 表单校验
const rules = ref({
  roleName: [
    {required: true, message: "角色名称不能为空", trigger: "blur"}
  ],
  roleKey: [
    {required: true, message: "权限字符不能为空", trigger: "blur"}
  ],
  roleSort: [
    {required: true, message: "角色顺序不能为空", trigger: "blur"}
  ]
})

if (userInfo.orgId) {
  queryParams.value.orgId = userInfo.orgId
  getList()
}

/** 左侧科室树节点点击事件 */
function treeClick(obj) {
  queryParams.value.orgId = obj.id
  getList()
}

/** 获取自定义服务列表 */
function getRoleGroup() {
  let param = {'orgId': queryParams.value.orgId}
  selectList(param).then(res => {
    chooseService.value = res.data
  })
}

/** 获取已选择的自定义服务列表 */
function getNotExistsRoleGroupFun() {
  let param = {'roleId': form.value.roleId, 'orgId': queryParams.value.orgId}
  getNotExistsRoleGroup(param).then((res: any) => {
    let data = res.data
    chooseService.value = data.list
    haveChooseService.value = data.haveChooseService
  })
}

// 角色状态修改
function handleStatusChange(row) {
  let text = row.status === "0" ? "启用" : "停用";
  ElMessageBox.confirm('确认要"' + text + '""' + row.roleName + '"角色吗？',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(function () {
    changeRoleStatus(row.roleId, row.status).then(() => {
      ElMessage.success(text + "成功");
    })
  }).catch(function () {
    row.status = row.status === "0" ? "1" : "0";
  });
}

// 表单重置
function reset() {
  if (menu.value != undefined) {
    menu.value.setCheckedKeys([]);
  }
  menuExpand.value = true
  menuNodeAll.value = false
  form.value = {
    roleId: undefined,
    roleName: undefined,
    roleKey: undefined,
    roleSort: 0,
    status: "0",
    menuIds: [],
    deptIds: [],
    menuCheckStrictly: true,
    remark: undefined,
    orgId: queryParams.value.orgId
  };
}

/** 搜索按钮操作 */
function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
}

/** 重置按钮操作 */
function resetQuery() {
  queryParamsRef.value.resetFields()
  dateRange.value = [];
  handleQuery();
}

// 多选框选中数据
function handleSelectionChange(selection) {
  ids.value = selection.map(item => item.roleId)
  single.value = selection.length != 1
  multiple.value = !selection.length
}

// 更多操作触发
function handleCommand(command, row) {
  switch (command) {
    case "handleAuthUser":
      handleAuthUser(row);
      break;
    default:
      break;
  }
}

/** 新增按钮操作 */
function handleAdd() {
  reset();
  if (!userInfo.orgId && !form.value.orgId) {
    return ElMessage.error("请先选择所属机构后再新增")
  }
  getRoleGroup()
  open.value = true;
  isAdd.value = true
  title.value = "添加角色";
}

/** 修改按钮操作 */
function handleUpdate(row) {
  reset();
  form.value = row
  isAdd.value = false
  form.value.roleId = row.roleId
  title.value = "修改角色";
  getNotExistsRoleGroupFun()
  open.value = true;
}

/** 点击修改组织权限菜单选中树 */
function setPermissionsTree(roleId) {
  const roleMenu = getSelectChooseRoleGroupMenu(roleId);
  open.value = true;
  nextTick(() => {
    roleMenu.then(res => {
      let checkedKeys = res.data
      if (checkedKeys.length === menuCount.value) {
        menuNodeAll.value = true
      } else {
        menuNodeAll.value = false
      }
      checkedKeys.forEach((v) => {
        nextTick(() => {
          menu.value.setChecked(v, true, false);
        })
      })
    });
  });
}

/** 根据角色ID查询菜单树结构 */
function getSelectChooseRoleGroupMenu(roleId) {
  let param = {"roleId": roleId, "roleGroupId": roleGroupId.value}
  return selectChooseRoleGroupMenu(param).then(response => {
    return response;
  });
}

// 树权限（展开/折叠）
function handleCheckedTreeExpand(value, type) {
  if (type == 'menu') {
    let treeList: any = menuOptions.value;
    for (let i = 0; i < treeList.length; i++) {
      menu.value.store.nodesMap[treeList[i].id].expanded = value;
    }
  } else if (type == 'dept') {
    let treeList = deptOptions.value;
    for (let i = 0; i < treeList.length; i++) {
      dept.value.store.nodesMap[treeList[i].id].expanded = value;
    }
  }
}

// 树权限（全选/全不选）
function handleCheckedTreeNodeAll(value, type) {
  if (type == 'menu') {
    menu.value.setCheckedNodes(value ? menuOptions.value : []);
  } else if (type == 'dept') {
    dept.value.setCheckedNodes(value ? deptOptions.value : []);
  }
}

// 树权限（父子联动）
function handleCheckedTreeConnect(value, type) {
  if (type == 'menu') {
    form.value.menuCheckStrictly = value ? true : false;
  } else if (type == 'dept') {
    form.value.deptCheckStrictly = value ? true : false;
  }
}

/** 分配用户操作 */
function handleAuthUser(row) {
  const roleId = row.roleId;
  const businessType = '1';
  router.push("/system/role-auth/user/" + queryParams.value.orgId + "/" + roleId + "/" + businessType);
}

/** 提交按钮 */
function submitForm() {
  (formRef.value as any).validate(valid => {
    if (valid) {
      form.value.roleGroupId = roleGroupId.value
      if (form.value.roleId !== undefined) {
        if (rightChoose.value.length <= 0) {
          return ElMessage.error("请勾选需要添加的权限数据后保存")
        }
        form.value.menuIds = getMenuAllCheckedKeys();
        if (form.value.menuIds.length <= 0) {
          return ElMessage.error("请勾选需要添加的权限数据后保存")
        }
        updateRole(form.value).then(_response => {
          ElMessage.success("修改成功");
          // this.open = false;
          getList();
        });
      } else {
        if (haveChooseService.value.length <= 0) {
          return ElMessage.error("请添加服务数据后保存")
        }
        let roleGroupIdArray: any[] = []
        haveChooseService.value.forEach((item: any) => {
          let roleGroupId = item.roleGroupId
          roleGroupIdArray.push(roleGroupId)
        })
        if (roleGroupIdArray.length > 0) {
          form.value.roleGroupIdArray = roleGroupIdArray
        }
        addRole(form.value).then(_response => {
          ElMessage.success("新增成功");
          open.value = false;
          handleQuery();
        });
      }
    }
  });
}

/** 删除按钮操作 */
function handleDelete(row) {
  const roleIds = row.roleId || ids.value;
  ElMessageBox.confirm('是否删除选中的数据项？',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(function () {
    delRole(roleIds).then(() => {
      getList();
      ElMessage.success("删除成功");
    })
  }).catch(() => {
  });
}

/** 右侧点击事件 */
function rightChooseChange(_val) {
  if (rightChoose.value.length > 1) {
    rightChoose.value.splice(0, 1)
  }
  if (rightChoose.value.length === 1) {
    menuOptions.value = []
    let roleGroupIdThis = rightChoose.value[0].roleGroupId
    roleGroupId.value = roleGroupIdThis
    // 新增
    roleGroupMenuTree(roleGroupIdThis).then(res => {
      let data = res.data
      menuCheckStrictly.value = data.menuCheckStrictly
      menuOptions.value = data.treeList
      menuCount.value = data.menuCount
      if (form.value.roleId) {
        // 修改
        setPermissionsTree(form.value.roleId)
      }
    })
  }
}

/** 选中事件 */
function theSelected() {
  if (leftChoose.value.length > 0) {
    leftChoose.value.forEach(item => {
      haveChooseService.value.push(item)
      chooseService.value.splice(chooseService.value.indexOf(item), 1)
    })
    leftChoose.value = []
  }
}

/** 删除已选择服务事件 */
function theCancel() {
  if (rightChoose.value.length > 0) {
    let param = {"roleId": form.value.roleId, "roleGroupId": rightChoose.value[0].roleGroupId}
    ElMessageBox.confirm("确定要删除名称为(" + rightChoose.value[0].roleGroupName + ")的服务吗？删除后所选权限不可恢复。",
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    ).then(function () {
      delChooseRoleGroup(param).then(() => {
        getList()
        menuOptions.value = []
        for (let i = rightChoose.value.length; i < rightChoose.value.length; i--) {
          const item = rightChoose.value[i]
          chooseService.value.push(item)
          haveChooseService.value.splice(haveChooseService.value.indexOf(item), 1)
        }
        rightChoose.value.forEach((item: any) => {
          chooseService.value.push(item)
          haveChooseService.value.splice(haveChooseService.value.indexOf(item), 1)
        })
        rightChoose.value = []
        ElMessage.success("删除成功");
      })
    }).catch(() => {
    });
  }
}

/** 关闭自定义服务dialog */
function chooseClose() {
  open.value = false
  chooseService.value = []
  haveChooseService.value = []
  leftChoose.value = []
  rightChoose.value = []
  menuOptions.value = []
  reset();
}

/** 查询角色列表 */
function getList() {
  if (!queryParams.value.orgId) {
    return ElMessage.error("请先选择左侧所属机构后查询")
  }
  listRole(proxy.$addDateRange(queryParams.value, dateRange.value)).then((response: any) => {
    roleList.value = response.rows;
    total.value = response.total;
  });
}

/** 左侧点击事件 */
function leftChooseChange(_val) {
}


// 所有菜单节点数据
function getMenuAllCheckedKeys() {
  // 目前被选中的菜单节点
  let checkedKeys = menu.value.getCheckedKeys();
  // 半选中的菜单节点
  let halfCheckedKeys = menu.value.getHalfCheckedKeys();
  checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
  return checkedKeys;
}
</script>
<script lang="ts">
export default {
  name: "DeptGroup"
}
</script>

<style scoped>
.parent-div {
  height: 440px;
  overflow: auto;
  width: 100%;
  display: flex;
}

:deep(.el-card__header) {
  padding: 5px 5px 5px 5px;
  background-color: rgb(226, 226, 226);
}

.check-service {
  margin-left: 10px
}

.tree-div {
  background-color: #F5F7FA;
  border: 1px solid #e6ebf5;
  padding-left: 15px;
}

.div-border {
  border: 1px solid #027687;
}

.group-menu-tree {
  height: calc(100% - 28px);
  overflow-y: auto;
  border: 1px solid #e6ebf5;
  border-radius: 4px;

}
</style>
